package tool.executor;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import tool.model.FilterModel;
import tool.model.FilterSwitch;
import tool.model.MainModel;

/**
 * 生成classlist 解压包 删除无用类
 * 
 * @author cody
 *
 */
public class Unpacker {
	
	private static List<File> files = new ArrayList<File>();
	/**
	 * 生成ClassList
	 * @param jreFloder
	 * @param jarFile
	 * @param model
	 * @param event
	 */
	public static void generateClassList(String jreFloder,String jarFile,MainModel model,UnpackEvent event) {
		Thread th = new Thread(()->{
			String jv = "java";
			if(model.getMode()==1) {
				jv = "javaw";
			}
			//生成ClassList
			String command =jreFloder+ File.separator+"bin"+File.separator+jv+" -jar -verbose "+jarFile+" >> "+jarFile.substring(0, jarFile.lastIndexOf("\\"))+"classlist.text";
			Process p;
			try {
				p = Runtime.getRuntime().exec(command);
				// 读取命令的输出信息
				InputStream is = p.getInputStream();
				BufferedReader reader = new BufferedReader(new InputStreamReader(is));
				//p.waitFor();
//				if (p.exitValue() != 0) {
//					// 说明命令执行失败
//					// 可以进入到错误处理步骤中
//				}
				// 打印输出信息
				ArrayList<ClassBean> sb = new ArrayList<ClassBean>();
				String s = null;
				while ((s = reader.readLine()) != null) {
					ClassBean classBean = parseClasses(s);
					if (classBean != null) {
						sb.add(classBean);
					}
				}
				model.setClassList(sb);
				event.generateDone();
			} catch (IOException e) {
				e.printStackTrace();
			}
		});
		th.start();
	}
	
	/**
	 * 解析已用的Class路径
	 * @param row
	 * @return
	 */
	public static ClassBean parseClasses(String row) {
		// TODO 拆分出所有类名和jar文件名
		String regex = "\\[Loaded (.*) from (.*)\\]";
		// Create a Pattern object
		Pattern r = Pattern.compile(regex);
		
		// Now create matcher object.
		Matcher m = r.matcher(row);
		if (m.find()) {
			ClassBean name = new ClassBean();
			name.setClassName(m.group(1));
			name.setJarFile(m.group(2));
			return name;
		}
		return null;
	}
	
	public static void unpack(String jreFloder,UnpackEvent event,String buildFloder) {
		//解压jre内所有jar包
		String libFloader = jreFloder+"\\lib";
		File dir = new File(libFloader);
		File[] files = dir.listFiles();
		Thread th = new Thread(()->{
			new File("./build").mkdirs();
			for (File file : files) {
				if (file.getName().matches("(.*)\\.jar")) {
					unpackOne(jreFloder,libFloader,file,buildFloder);
				}
			}
			event.exDone();
		});
		th.start();
	}
	
	private static void unpackOne(String jreFloader,String libFloader,File jarFile,String buildFloder) {
		
		String command = jreFloader + "\\bin\\java -jar "
				+ "\""+buildFloder+"\\ujc.jar\" "
				+ "\""+jreFloader+"\" "
				+ "\""+jarFile.getAbsolutePath()+"\"";
		command =new File(jreFloader).getParent()+ "\\bin\\jar xf \""+jarFile.getAbsolutePath()+"\"";
		System.out.println(command);
		Process p;
		try {
			p = Runtime.getRuntime().exec(command,null, new File(buildFloder));
			// 读取命令的输出信息
			InputStream is = p.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(is));
			//p.waitFor();
//			if (p.exitValue() != 0) {
//				// 说明命令执行失败
//				// 可以进入到错误处理步骤中
//			}
			// 打印输出信息
			String s;
			while ((s = reader.readLine()) != null) {
				System.out.println("解压："+jarFile.getAbsolutePath()+s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	public static void deleteFiles(MainModel model,UnpackEvent event,boolean isTest,boolean useFilter,FilterSwitch filterSwitch) {
		files.clear();
		takeFiles(new File("./build/"));
		if (useFilter) {
			try {
				if(model.getMode()>0) {
					filterSwitch.setEnableJavaFX(false);//非桌面图形界面程序均禁止javafx
				}
				if(model.getMode()>1) {
					filterSwitch.setEnableSunUtil(true);//高级程序必须保留Sun.Util
				}
				files = FilterModel.filter(files,filterSwitch);
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
		}
		for (File file : files) {
			boolean delable = true;
			for (ClassBean clazz : model.getClassList()) {
					String cnn = clazz.getClassName().substring(clazz.getClassName().lastIndexOf(".")+1);
					if (file.getName().indexOf(cnn+".class")>-1) {
						delable = false;//不让他删除
						break;
					}
			}
			if (delable) {
				System.out.println("删除文件："+file.getName());
				if (!isTest) {
					file.delete();
				}
			}
		}
		event.delDone();
	}
	
	protected void deleteFloder() {
		// TODO 只控制删除“未经使用的文件夹”不删除所有未经使用的文件，屠宰级别较低，生成的jar更安全

	}
	
	protected static void takeFiles(File f){
        if(f!=null){
            if(f.isDirectory()){
                File[] fileArray=f.listFiles();
                if(fileArray!=null){
                    for (int i = 0; i < fileArray.length; i++) {
                        //递归调用
                    	takeFiles(fileArray[i]);
                    }
                }
            }
            else{
            	files.add(f);
            }
        }
    }
}
